1//////////////////////////////////////////////////////////////////////////
  2// LibFile: modular_hose.scad
  3//   Modular hose segment and attachment ends. 
  4// Includes:
  5//   include <BOSL2/std.scad>
  6//   include <BOSL2/modular_hose.scad>
  7// FileGroup: Parts
  8// FileSummary: Modular flexible hose segments.
  9//////////////////////////////////////////////////////////////////////////
 10
 11// Section: Modular Hose Parts
 12
 13_modhose_small_end = [
 14             turtle([
 15                     "left", 90-38.5,            //   1/4" hose
 16                     "arcsteps", 12, 
 17                     "arcleft", 6.38493, 62.15,
 18                     "arcsteps", 4,
 19                     "arcleft", .5, 90+38.5-62.15,
 20                     "move", .76,
 21                     "left", 67.5,
 22                     "move", .47,
 23                     "left", 90-67.5,
 24                     "move", 4.165,
 25                     "right", 30,
 26                     "move", 2.1
 27                    ],
 28                    state=[4.864,0]),
 29             turtle([                            //   1/2" hose
 30                     "left", 90-41,
 31                     "arcsteps", 16, 
 32                     "arcleft", 10.7407, 64.27,
 33                     "arcsteps", 4,
 34                     "arcleft", .5, 90+41-64.27,
 35                     "move", .95-.4,
 36                     "left", 45,
 37                     "move", .4*sqrt(2), 
 38                     "left",45,
 39                     "move", 7.643-.4,
 40                     "right", 30,
 41                     "move", 4.06
 42                   ],
 43                   state=[8.1, 0]),
 44             turtle([                            //   3/4" hose
 45                     "left", 90-30.4,
 46                     "arcsteps", 16,
 47                     "arcleft", 13.99219,53,
 48                     "arcsteps", 4, 
 49                     "arcleft", .47,90-53+30.4,
 50                     "move", .597,
 51                     "left", 
 52                     "move", 9.908-1.905/tan(25) +3.81*cos(30),  // Change to 25 deg angle
 53                     "right", 25,                                // to remove narrow point in wall
 54                     "move",1.905 /sin(25),
 55                  ],
 56                  state=[11.989,0])
 57            ];
 58  
 59
 60_modhose_big_end = [
 61           turtle([                            //   1/4" hose
 62                   "left", 90-22,
 63                   "move", 6.5,
 64                   "left",.75,
 65                   "arcsteps", 8,
 66                   "arcleft", 6.5, 37.3,
 67                   "setdir",90,
 68                   "move", .21,
 69                   "right",
 70                   "move", 1.24,
 71                   "right", 45,
 72                   "move", .7835,
 73                   "right", 19, 
 74                   "move", 1.05,
 75                   "setdir", -90,
 76                   "move", 1,
 77                   "right", 22,
 78                   "move", 8.76
 79                  ],
 80                  state = [3.268,0]),
 81           turtle([                            //   1/2" hose
 82                   "left",     
 83                   "right", 22,
 84                   "move", 9,
 85                   "arcsteps", 8,
 86                   "arcleft", 11, 36.5,
 87                   "setdir",90,
 88                   "move",2-1.366,
 89                   "right",
 90                   "move",.91,
 91                   "arcsteps", 4, 
 92                   "arcright", 1.25, 90,
 93                   "move", 2.2,
 94                   "arcsteps", 8, 
 95                   "arcright", 13, 22.4,
 96                   "move", 8.73
 97                  ],
 98                  state=[6.42154, 0]),
 99           turtle([                            //   3/4" hose
100                   "left", 90-22, 
101                   "move", 7.633,
102                   "arcsteps", 16,
103                   "arcleft", 13.77, 35.27,
104                   "setdir", 90,
105                   "move", 1.09,
106                   "right",
107                   "move",1.0177,
108                   "right", 45,
109                   "move", 1.009,
110                   "right", 77.8-45,
111                   "move", .3,
112                   "arcright", 15.5, 34.2,
113                   "move", 6.47
114                  ],
115                  state=[9.90237,0])
116        ];
117
118
119_modhose_waist = [1.7698, 1.8251, 3.95998];
120
121
122// Module: modular_hose()
123// Synopsis: Creates modular hose parts.
124// Topics: Modular Hose, Parts
125// See Also: modular_hose_radius(), tube()
126// Usage:
127//    modular_hose(size, type, [clearance], [waist_len], [anchor], [spin], [orient]) [ATTACHMENTS];
128// Description:
129//    Construct moduler hose segments or modular hose ends for connection to standard
130//    modular hose systems.  The 1/4", 1/2" and 3/4" sizes are supported and you can
131//    produce just one end to make a mount or end attachment to a modular hose,
132//    or you can make modular hose segments.  To make assembly possible with printed
133//    parts you can add clearances that make the ball end smaller and the socket end
134//    larger.  These work by simply increasing the radius of the whole end by the specified
135//    amount.  On a Prusa printer with PETG, a clearance of 0.05 allows the 3/4" hose parts to mate
136//    with standard modular hose or itself.  A clearance of 0.05 to 0.1 allows the 1/2" parts to mate with
137//    standard hose, and with clearance 0 the 1/4" parts will mate with standard hose.  Note that clearance values
138//    are different for the different sizes.  You will have to experiment with your machine and materials.  Small
139//    adjustments will change the stiffness of the connection.
140// Arguments:
141//    size = size of modular hose part, must be 1/4, 1/2 or 3/4.
142//    type = type of part to make, either "segment", "socket" (or "big"), or "ball" (or "small")
143//    clearance = clearance to make assembly possible.  Either a scalar to apply the same to both ends or a vector [small,large] to apply different clearances to the two ends.  Default: 0
144//    waist_len = size of central "waist" of the part.  Default: standard length.
145// Example:
146//    modular_hose(1/4,"segment");
147//    right(25)modular_hose(1/2,"segment");
148//    right(60)modular_hose(3/4,"segment");
149// Example: A mount point for modular hose
150//    cylinder(h=10, r=20)
151//       attach(TOP) modular_hose(1/2, "ball", waist_len=15);
152// Example: Mounting plate for something at the end of the hose
153//    cuboid([50,50,5])
154//       attach(TOP) modular_hose(3/4, "socket", waist_len=0);
155function modular_hose(size, type, clearance=0, waist_len, anchor=BOTTOM, spin=0,orient=UP) = no_function("modular_hose");
156module modular_hose(size, type, clearance=0, waist_len, anchor=BOTTOM, spin=0,orient=UP)
157{
158  clearance = force_list(clearance,2);
159  ind = search([size],[1/4, 1/2, 3/4])[0];
160  sbound =
161    assert(ind!=[], "Must specify size as 1/4, 1/2 or 3/4")
162    pointlist_bounds(_modhose_small_end[ind]);
163  bbound = pointlist_bounds(_modhose_big_end[ind]);
164  smallend =
165    assert(is_vector(clearance,2), "Clearance must be a scalar or length 2 vector")
166    move([-clearance[0],-sbound[0].y],p=_modhose_small_end[ind]);
167  bigend = move([clearance[1], -bbound[0].y], p=_modhose_big_end[ind]);
168
169  midlength = first_defined([waist_len, _modhose_waist[ind]]);
170  dummy = assert(midlength>=0,"midlength must be nonnegative");
171
172  goodtypes = ["small","big","segment","socket","ball"];
173  shape =
174    assert(in_list(type,goodtypes), str("type must be one of ",goodtypes))
175    type=="segment"? concat(back(midlength,p=smallend),yflip(p=bigend))
176  : type=="small" || type=="ball" ?
177          concat(back(midlength,p=smallend),
178                 [[last(smallend).x,0],[ smallend[0].x,0]])
179  : concat( back(midlength,p=bigend), 
180                  [[last(bigend).x,0],[ bigend[0].x,0]]);
181  bounds = pointlist_bounds(shape);
182  center = mean(bounds);
183  attachable(anchor,spin,orient,l=bounds[1].y-bounds[0].y, r=bounds[1].x)
184  {
185    rotate_extrude(convexity=4)
186      polygon(fwd(center.y,p=shape));
187    children();
188  }  
189}
190
191
192// Function: modular_hose_radius()
193// Synopsis: Returns the waist radius of the given modular hose size.
194// Topics: Modular Hose, Parts
195// See Also: modular_hose(), tube()
196// Usage:
197//   r = modular_hose_radius(size, [outer]);
198// Description:
199//   Returns the inner (or outer) diameter of the waist section
200//   of the modular hose to enable hollowing out connecting channels.
201//   Note: diameter is accurate to about 1e-4.  
202// Arguments:
203//   size = size of hose part, must be 1/4, 1/2 or 3/4
204//   outer = set to true to get the outer diameter. 
205// Example(3D):
206//   $fn=64;
207//   back_half()
208//      diff("remove")
209//        cuboid(50){
210//          attach(TOP) modular_hose(1/2, "ball");
211//          up(0.01)position(TOP+RIGHT)tag("remove")
212//            rot(180)
213//            xrot(-90)
214//            rotate_extrude(angle=135)
215//            right(25)
216//            circle(r=modular_hose_radius(1/2));
217//        }
218function modular_hose_radius(size, outer=false) =
219  let(
220      ind = search([size],[1/4, 1/2, 3/4])[0]
221  )
222  assert(ind!=[], "Must specify size as 1/4, 1/2 or 3/4")
223  let(
224     b = select(_modhose_big_end[ind], [0,-1]),
225     s = select(_modhose_small_end[ind], [0,-1])
226  )
227  outer ? b[1][0] : b[0][0];
228
229
230
231// vim: expandtab tabstop=4 shiftwidth=4 softtabstop=4 nowrap